package com.csw.shuanfa.CodeImprove.exercise.future;

import com.csw.shuanfa.utils.ThreadPoolUtil;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Fox
 * 烧水泡茶程序
 */
public class CompletableFuture_ThenCombine {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService threadPool = ThreadPoolUtil.getExecutorServiceCPU();

        try {
            //任务1：洗水壶->烧开水
            CompletableFuture<Void> f1 = CompletableFuture
                    .runAsync(() -> {
                        System.out.println("T1:洗水壶...");
                        sleep(1, TimeUnit.SECONDS);

                        System.out.println("T1:烧开水...");
                        sleep(15, TimeUnit.SECONDS);
                    }, threadPool);

            //任务2：洗茶壶->洗茶杯->拿茶叶
            CompletableFuture<String> f2 = CompletableFuture
                    .supplyAsync(() -> {
                        System.out.println("T2:洗茶壶...");
                        sleep(1, TimeUnit.SECONDS);

                        System.out.println("T2:洗茶杯...");
                        sleep(2, TimeUnit.SECONDS);

                        System.out.println("T2:拿茶叶...");
                        sleep(1, TimeUnit.SECONDS);
                        return "龙井";
                    }, threadPool);

            //任务3：任务1和任务2完成后执行：泡茶
            //第一个没参数，第二个有参数
            CompletableFuture<String> f3 = f1.thenCombine(f2, (__, tf) -> {
                System.out.println("T1:拿到茶叶:" + tf);
                System.out.println("T1:泡茶...");
                int aa = 1 / 0;
                return "上茶:" + tf;
            });
            //等待任务3执行结果
            System.out.println(f3.join());
        } catch (Exception e) {
            threadPool.shutdown();
            throw new RuntimeException(e);
        }


    }

    static void sleep(int t, TimeUnit u) {
        try {
            u.sleep(t);
        } catch (InterruptedException e) {
        }
    }
}
